﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using CSCore;
using CSCore.SoundIn;
using CSCore.SoundOut;
using CSCore.Streams;
using FM.Common;
using FM.Events;
using FM.Services;
using FM.录音.Data;
using FM.录音.接口;
using FM.接口;
using Microsoft.Practices.Prism.Logging;
using Microsoft.Practices.Prism.PubSubEvents;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.Unity;


namespace FM.录音.Services
{
    public class 监视服务1 : 启动基类, I监视服务
    {
        private double _left;
        private double _right;
        private double _peakUpdateCounter;
        private IWaveSource _finalSource;
        private WasapiCapture _soundIn;
        private IFm录音配置 _录音配置;
        private I电平表 _电平表2 = new 电平表1();

        public 监视服务1(IUnityContainer 人事部cs, IEventAggregator 新闻部cs, IRegionManager 模块cs)
            : base(人事部cs, 新闻部cs, 模块cs)
        {
            新闻部.GetEvent<退出Event>().Subscribe(退出Action, true);
        }

        private void 退出Action(object obj)
        {
            停止监视();
        }

        public bool Is监视中 { get; private set; }

        public event EventHandler<I电平表> 电平更新EventHandler = delegate { };
        public int ID { get; set; }
        public IFm录音配置 录音配置
        {
            get { return _录音配置; }
            set { _录音配置 = value; }
        }

        public void 启动监视()
        {
            if (Is监视中)
            {
                return;
            }

            自检();
            var 声卡1 = 声卡设备.查找输入声卡(录音配置.录音声卡);

            if (声卡1 == null)
            {
                新闻部.GetEvent<状态栏更新Event>().Publish(new 状态栏Data1(Enum状态栏.提示, ID + "没有输入声卡"));
                return;
            }
            Is监视中 = true;
            if (录音配置.录音声卡 != 声卡1.FriendlyName)
            {
                录音配置.录音声卡 = 声卡1.FriendlyName;
            }

            _soundIn = new WasapiCapture { Device = 声卡1 };
            _soundIn.Initialize();

            var soundInSource = new SoundInSource(_soundIn);
            var singleBlockNotificationStream = new SingleBlockNotificationStream(soundInSource);
            _finalSource = singleBlockNotificationStream.ToWaveSource();

            byte[] buffer = new byte[_finalSource.WaveFormat.BytesPerSecond / 2];
            soundInSource.DataAvailable += (s, e) => { _finalSource.Read(buffer, 0, buffer.Length); };
            singleBlockNotificationStream.SingleBlockRead += 收到信号电平处理;
            _soundIn.Start();
        }

        private void 自检()
        {
            if (录音配置 == null)
            {
                录音配置 = new Fm录音配置1();
                log.Log("监视服务启动时未找到配置", Category.Warn, Priority.High  );
            }
        }

        public void 停止监视()
        {
            if (!Is监视中)
            {
                return;
            }

            Is监视中 = false;

            if (_soundIn != null)
            {
                _soundIn.Stop();
                _soundIn.Dispose();
            }
            if (_finalSource != null)
                _finalSource.Dispose();

            _电平表2.左电平 = _电平表2.右电平 = 0;
            电平更新EventHandler(this, _电平表2);
        }

        private void 收到信号电平处理(object sender, SingleBlockReadEventArgs e)
        {
            _left = Math.Max((int)(Math.Abs(e.Left) * 10000), _left);
            _right = Math.Max((int)(Math.Abs(e.Right) * 10000), _right);
            var l2 = _left;
            var r2 = _right;
            if (++_peakUpdateCounter >= 44100 / 10)
            {
                _电平表2.左电平 = l2 / 10000;
                _电平表2.右电平 = r2 / 10000;
                _peakUpdateCounter = _left = _right = 0;

                电平更新EventHandler(this, _电平表2);
            }
        }

        public void Set监视(bool 电平监视)
        {
            if (电平监视 && !Is监视中)
            {
                启动监视();
            }
            else if (!电平监视 && Is监视中)
            {
                停止监视();
            }
        }




    }
}